<!DOCTYPE html>

















































<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <meta name="description" content="Javadoc API documentation for Dormancy." />

<link rel="shortcut icon" type="image/x-icon" href="../../../favicon.ico" />
<title>

  DormancyUtils


| Dormancy

</title>
<link href="../../../../assets/doclava-developer-docs.css" rel="stylesheet" type="text/css" />
<link href="../../../../assets/customizations.css" rel="stylesheet" type="text/css" />
<script src="../../../../assets/search_autocomplete.js" type="text/javascript"></script>
<script src="../../../../assets/jquery-resizable.min.js" type="text/javascript"></script>
<script src="../../../../assets/doclava-developer-docs.js" type="text/javascript"></script>
<script src="../../../../assets/prettify.js" type="text/javascript"></script>
<script type="text/javascript">
  setToRoot("../../../", "../../../../assets/");
</script>
<script src="../../../../assets/doclava-developer-reference.js" type="text/javascript"></script>
<script src="../../../../assets/navtree_data.js" type="text/javascript"></script>
<script src="../../../../assets/customizations.js" type="text/javascript"></script>
<noscript>
  <style type="text/css">
    html,body{overflow:auto;}
    #body-content{position:relative; top:0;}
    #doc-content{overflow:visible;border-left:3px solid #666;}
    #side-nav{padding:0;}
    #side-nav .toggle-list ul {display:block;}
    #resize-packages-nav{border-bottom:3px solid #666;}
  </style>
</noscript>
</head>

<body class="">

<div id="header">
    <div id="headerLeft">
    
      <span id="masthead-title">Dormancy</span>
    
    </div>
    <div id="headerRight">
      
  <div id="search" >
      <div id="searchForm">
          <form accept-charset="utf-8" class="gsc-search-box" 
                onsubmit="return submit_search()">
            <table class="gsc-search-box" cellpadding="0" cellspacing="0"><tbody>
                <tr>
                  <td class="gsc-input">
                    <input id="search_autocomplete" class="gsc-input" type="text" size="33" autocomplete="off"
                      title="search developer docs" name="q"
                      value="search developer docs"
                      onFocus="search_focus_changed(this, true)"
                      onBlur="search_focus_changed(this, false)"
                      onkeydown="return search_changed(event, true, '../../../')"
                      onkeyup="return search_changed(event, false, '../../../')" />
                  <div id="search_filtered_div" class="no-display">
                      <table id="search_filtered" cellspacing=0>
                      </table>
                  </div>
                  </td>
                  <td class="gsc-search-button">
                    <input type="submit" value="Search" title="search" id="search-button" class="gsc-search-button" />
                  </td>
                  <td class="gsc-clear-button">
                    <div title="clear results" class="gsc-clear-button">&nbsp;</div>
                  </td>
                </tr></tbody>
              </table>
          </form>
      </div><!-- searchForm -->
  </div><!-- search -->
      
    </div>
</div><!-- header -->


  <div class="g-section g-tpl-240" id="body-content">
    <div class="g-unit g-first side-nav-resizable" id="side-nav">
      <div id="swapper">
        <div id="nav-panels">
          <div id="resize-packages-nav">
            <div id="packages-nav">
              <div id="index-links"><nobr>
                <a href="../../../packages.html"  >Package Index</a> | 
                <a href="../../../classes.html" >Class Index</a></nobr>
              </div>
              <ul>
                
    <li class="api apilevel-">
  <a href="../../../at/dormancy/package-summary.html">at.dormancy</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/access/package-summary.html">at.dormancy.access</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/aop/package-summary.html">at.dormancy.aop</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persistence/package-summary.html">at.dormancy.persistence</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persister/package-summary.html">at.dormancy.persister</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persister/callback/package-summary.html">at.dormancy.persister.callback</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persister/filter/package-summary.html">at.dormancy.persister.filter</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persister/function/package-summary.html">at.dormancy.persister.function</a></li>
    <li class="api apilevel-">
  <a href="../../../at/dormancy/persister/predicate/package-summary.html">at.dormancy.persister.predicate</a></li>
    <li class="selected api apilevel-">
  <a href="../../../at/dormancy/util/package-summary.html">at.dormancy.util</a></li>
              </ul><br/>
            </div> <!-- end packages -->
          </div> <!-- end resize-packages -->
          <div id="classes-nav">
            <ul>
              
              
    <li><h2>Classes</h2>
      <ul>
          <li class="api apilevel-"><a href="../../../at/dormancy/util/AbstractDormancyUtils.html">AbstractDormancyUtils</a>&lt;PU,&nbsp;PC,&nbsp;PMD,&nbsp;PUP&nbsp;extends&nbsp;<a href="../../../at/dormancy/persistence/PersistenceUnitProvider.html">PersistenceUnitProvider</a>&lt;PU,&nbsp;PC,&nbsp;PMD&gt;&gt;</li>
          <li class="api apilevel-"><a href="../../../at/dormancy/util/ClassLookup.html">ClassLookup</a></li>
          <li class="selected api apilevel-"><a href="../../../at/dormancy/util/DormancyUtils.html">DormancyUtils</a></li>
          <li class="api apilevel-"><a href="../../../at/dormancy/util/IntrospectorUtils.html">IntrospectorUtils</a></li>
          <li class="api apilevel-"><a href="../../../at/dormancy/util/JpaProviderUtils.html">JpaProviderUtils</a></li>
      </ul>
    </li>
              
              
              
              
            </ul><br/>
          </div><!-- end classes -->
        </div><!-- end nav-panels -->
        <div id="nav-tree" style="display:none">
          <div id="index-links"><nobr>
            <a href="../../../packages.html"  >Package Index</a> | 
            <a href="../../../classes.html" >Class Index</a></nobr>
          </div>
        </div><!-- end nav-tree -->
      </div><!-- end swapper -->
    </div> <!-- end side-nav -->
    <script>
      if (!isMobile) {
        $("<a href='#' id='nav-swap' onclick='swapNav();return false;' style='font-size:10px;line-height:9px;margin-left:1em;text-decoration:none;'><span id='tree-link'>Use Tree Navigation</span><span id='panel-link' style='display:none'>Use Panel Navigation</span></a>").appendTo("#side-nav");
        chooseDefaultNav();
        if ($("#nav-tree").is(':visible')) {
          init_default_navtree("../../../");
        } else {
          addLoadEvent(function() {
            scrollIntoView("packages-nav");
            scrollIntoView("classes-nav");
          });
        }
        $("#swapper").css({borderBottom:"2px solid #aaa"});
      } else {
        swapNav(); // tree view should be used on mobile
      }
    </script>



<div class="g-unit" id="doc-content">

<div id="api-info-block">



  
   
  
  
  
   
  
  

  
   
  
  
  
  


<div class="sum-details-links">

<div>
<a href="DormancyUtils.html">View Documentation</a>
</div>


</div><!-- end sum-details-links -->
<div class="api-level">
  


  
  

</div>
</div><!-- end api-info-block -->


<!-- ======== START OF CLASS DATA ======== -->

<div id="jd-header">
    public
     
     
    
    class
<h1>DormancyUtils</h1>



  
  
  

  
    extends <a href="../../../at/dormancy/util/AbstractDormancyUtils.html">AbstractDormancyUtils</a>&lt;PU,&nbsp;PC,&nbsp;PMD,&nbsp;PUP&nbsp;extends&nbsp;<a href="../../../at/dormancy/persistence/PersistenceUnitProvider.html">PersistenceUnitProvider</a>&lt;PU,&nbsp;PC,&nbsp;PMD&gt;&gt;<br/>
  
  
  

  
  
  


</div><!-- end header -->
<div id="jd-content">
  <pre class="prettyprint">
/*
 * Copyright 2013 Gregor Schauer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package at.dormancy.util;

import at.dormancy.access.AbstractPropertyAccessStrategy;
import at.dormancy.access.HibernatePropertyAccessStrategy;
import at.dormancy.access.StrategyPropertyAccessor;
import at.dormancy.persistence.HibernatePersistenceUnitProvider;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.hibernate.*;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.internal.AbstractSessionImpl;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.PropertyAccessor;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * Utility methods for Dormancy support code.
 *
 * @author Gregor Schauer
 */
public class DormancyUtils extends AbstractDormancyUtils&lt;SessionFactory, Session, ClassMetadata,
		HibernatePersistenceUnitProvider&gt; {

	@Inject
	public DormancyUtils(@Nonnull HibernatePersistenceUnitProvider persistenceUnitProvider) {
		super(persistenceUnitProvider);
	}

	@Nullable
	@Override
	public ClassMetadata getMetadata(@Nullable Class&lt;?&gt; clazz) {
		return clazz != null ? persistenceUnitProvider.getMetadata(clazz) : null;
	}

	/**
	 * @see ClassMetadata#getMappedClass()
	 */
	@Nonnull
	@Override
	public Class&lt;?&gt; getMappedClass(@Nonnull ClassMetadata metadata) {
		return metadata.getMappedClass();
	}

	@Nonnull
	@Override
	public String getEntityName(@Nonnull Class&lt;?&gt; clazz) {
		ClassMetadata metadata = getMetadata(clazz);
		return metadata != null ? metadata.getEntityName() : clazz.getSimpleName();
	}

	@Nullable
	@Override
	protected String getIdentifierPropertyName(@Nonnull Class&lt;?&gt; clazz) {
		ClassMetadata metadata = getMetadata(clazz);
		return metadata != null ? metadata.getIdentifierPropertyName() : null;
	}

	@Override
	@Nullable
	public &lt;T&gt; Serializable getIdentifier(@Nonnull ClassMetadata metadata, @Nonnull T bean) {
		Serializable identifier = metadata.getIdentifier(bean, (AbstractSessionImpl) getPersistenceContext());
		if (identifier == null) {
			identifier = Serializable.class.cast(getPropertyValue(metadata, bean, metadata.getIdentifierPropertyName()));
		}
		return identifier;
	}

	@Override
	public boolean isVersioned(@Nonnull ClassMetadata metadata) {
		return metadata.isVersioned();
	}

	@Nullable
	@Override
	public String getVersionPropertyName(@Nonnull ClassMetadata metadata) {
		int index = metadata.getVersionProperty();
		return index &gt;= 0 ? metadata.getPropertyNames()[index] : null;
	}

	@Override
	@Nullable
	public Object getPropertyValue(@Nullable ClassMetadata metadata, @Nonnull Object bean, @Nonnull String propertyName) {
		return IntrospectorUtils.getValue(bean, propertyName);
	}

	@Override
	public void setPropertyValue(@Nullable ClassMetadata metadata, @Nonnull Object bean, @Nonnull String propertyName, @Nullable Object value) {
		IntrospectorUtils.setValue(bean, propertyName, value);
	}

	@Nonnull
	@Override
	public Class&lt;?&gt; getPropertyType(@Nonnull Class&lt;?&gt; clazz, @Nonnull String propertyName) {
		ClassMetadata metadata = getMetadata(clazz);
		if (metadata != null) {
			try {
				return metadata.getPropertyType(propertyName).getReturnedClass();
			} catch (QueryException e) {
				if (ArrayUtils.contains(metadata.getPropertyNames(), propertyName)) {
					throw e;
				}
			}
		}
		return ReflectionUtils.findField(clazz, propertyName).getType();
	}

	@Nullable
	@Override
	public PropertyAccessor getPropertyAccessor(@Nullable ClassMetadata metadata, @Nonnull Object obj) {
		if (metadata == null) {
			return PropertyAccessorFactory.forDirectFieldAccess(obj);
		}
		if (isJavassistProxy(obj.getClass())) {
			// If the object is a proxy, attempt to find its LazyInitializer
			Field handlerField = ReflectionUtils.findField(obj.getClass(), "handler");
			if (handlerField != null) {
				// If the LazyInitializer is available, obtain the underlying object
				LazyInitializer lazyInitializer = (LazyInitializer) ReflectionTestUtils.getField(obj, "handler");
				// Initialize it if necessary and return a DirectFieldAccessor for the nested object
				obj = lazyInitializer.getImplementation();
			} else {
				/*
				 * Otherwise log a warning message because this is very unlikely to happen or even impossible.
				 * However, instead of throwing an exception, property access is used as a fallback solution.
				 */
				Logger.getLogger(getClass()).warn("Cannot retrieve field named 'handler' of type 'org.hibernate.proxy.LazyInitializer' from " + ObjectUtils.identityToString(obj));
			}
		}
		return new StrategyPropertyAccessor(obj, getPropertyAccessStrategy(AopUtils.getTargetClass(obj)));
	}

	@Nonnull
	@Override
	protected AbstractPropertyAccessStrategy createStrategy(@Nonnull Class&lt;?&gt; clazz) {
		return new HibernatePropertyAccessStrategy(clazz);
	}

	@Nullable
	@Override
	@SuppressWarnings("unchecked")
	public &lt;T&gt; T find(@Nonnull Class&lt;T&gt; clazz, @Nonnull Serializable id) {
		return (T) getPersistenceContext().get(clazz, id);
	}

	@Override
	public void flush() {
		getPersistenceContext().flush();
	}

	@Nonnull
	@Override
	@SuppressWarnings("unchecked")
	public &lt;K&gt; K persist(@Nonnull Object obj) {
		return (K) getPersistenceContext().save(obj);
	}

	/**
	 * @see #isInitialized(Object)
	 * @see HibernateProxy
	 */
	@Override
	public boolean isProxy(@Nullable Object obj) {
		return obj instanceof HibernateProxy;
	}

	/**
	 * @see Hibernate#isInitialized(Object)
	 */
	@Override
	public boolean isInitialized(@Nullable Object obj) {
		return Hibernate.isInitialized(obj);
	}

	@Override
	public boolean isUninitialized(@Nonnull String propertyName, @Nonnull Object dbObj, @Nonnull Object dbValue, @Nullable Object trValue) {
		HibernateProxy hibernateProxy = HibernateProxy.class.cast(dbValue);
		LazyInitializer lazyInitializer = hibernateProxy.getHibernateLazyInitializer();
		if (lazyInitializer.isUninitialized()) {
			// If property is loaded lazily, the value of the given object must be null
			if (trValue != null) {
				throw throwLazyPropertyNotNullException(trValue, dbObj, propertyName);
			}
			return true;
		}
		return false;
	}

	@Override
	public boolean isPersistentCollection(@Nullable Object obj) {
		return obj instanceof PersistentCollection;
	}

	/**
	 * @see PersistentCollection#wasInitialized()
	 */
	@Override
	public boolean isInitializedPersistentCollection(@Nullable Object obj) {
		return isPersistentCollection(obj) &amp;&amp; PersistentCollection.class.cast(obj).wasInitialized();
	}

	/**
	 * Throws a {@link TransientObjectException} indicating that the object has no valid identifier.
	 *
	 * @throws TransientObjectException the exception
	 */
	@Override
	public RuntimeException throwNullIdentifierException(@Nonnull Object object) {
		throw new TransientObjectException("The given object has a null identifier: " + getEntityName(getClass(object)));
	}

	/**
	 * Throws a {@link TransientObjectException} indicating that the object must be saved manually before continuing.
	 *
	 * @throws TransientObjectException the exception
	 */
	@Override
	public RuntimeException throwUnsavedTransientInstanceException(@Nonnull Object object) {
		throw new TransientObjectException(
				"object references an unsaved transient instance - save the transient instance before flushing: " +
						getEntityName(getClass(object))
		);
	}

	/**
	 * Throws a {@link PropertyValueException} when a lazy property holds a value while {@code null} was expected.
	 *
	 * @throws PropertyValueException the exception
	 */
	@Override
	public RuntimeException throwLazyPropertyNotNullException(@Nonnull Object trValue, @Nonnull Object dbObj, @Nonnull String propertyName) {
		throw new PropertyValueException("Property is loaded lazily. Therefore it must be null but was: " + trValue,
				getEntityName(getClass(dbObj)), propertyName);
	}

	/**
	 * Throws a {@link StaleObjectStateException} when an optimistic locking conflict occurs.
	 *
	 * @throws StaleObjectStateException the exception
	 */
	@Override
	public RuntimeException throwOptimisticLockException(@Nonnull Object dbValue, @Nonnull Serializable identifier) {
		throw new StaleObjectStateException(getEntityName(getClass(dbValue)), identifier);
	}

	/**
	 * Throws an {@link ObjectNotFoundException} when an entity reference is accessed but the entity does not exist.
	 *
	 * @throws ObjectNotFoundException the exception
	 */
	@Override
	public RuntimeException throwEntityNotFoundException(@Nonnull Serializable identifier, @Nonnull Object trObj) {
		throw new ObjectNotFoundException(identifier, getClass(trObj).getSimpleName());
	}

	/**
	 * Throws a {@link PropertyValueException} when a property is not accessible or holds an unexpected value.
	 *
	 * @throws PropertyValueException the exception
	 */
	@Override
	public RuntimeException throwPropertyValueException(@Nonnull String message, @Nonnull Object bean) {
		throw new PropertyValueException(message, getEntityName(bean.getClass()), getIdentifierPropertyName(bean.getClass()));
	}

	@Nonnull
	@Override
	public Session getPersistenceContext() {
		return persistenceUnitProvider.getPersistenceContextProvider().getPersistenceContext();
	}
}

  </pre>
</div>
<div id="footer">
Generated by <a href="http://code.google.com/p/doclava/">Doclava</a>.
</div> <!-- end footer -->

</div> <!-- jd-content -->

</div><!-- end doc-content -->

</div> <!-- end body-content --> 

<script type="text/javascript">
init(); /* initialize doclava-developer-docs.js */
</script>

</body>
</html>
